#include<bits/stdc++.h>
using namespace std;
int nums[10000];

void selectSort(int n) {
    for (int i = 0; i < n; i++) {
        int min_index = i;//假设第一个为最小的
        for (int j = i; j < n; j++) {
            if (nums[j] < nums[min_index]) {
                min_index = j;//找更小的
            }
        }
        swap(nums[i],nums[min_index]);//交换
    }
}
void bubbleSort(int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (nums[j] > nums[j+1]) {
                swap(nums[j],nums[j+1]);
            }
        }
    }
}
void insertSort(int n) {
    for (int i = 1;i < n; i++) {//认为0号元素已排序过
        int temp = nums[i];//被拿出来排序的数字
        int j = i - 1;
        while (j >= 0 && nums[j] > temp) {
            nums[j + 1] = nums[j];//比要排序的数字大的所有元素往后移
            j = j - 1;
        }
        nums[j + 1] = temp;//补空缺
    }
}
void merge(int arr[], int start, int mid, int end) {
    int result[100];//用辅助数组来存储自己排序后的数组
    int k = 0;
    int i = start;
    int j = mid + 1;
    while (i <= mid && j <= end) {//双指针作比较，谁小放谁进去【因为左右两边都是有序序列】
        if (arr[i] < arr[j]){
            result[k++] = arr[i++];
        }
        else{
            result[k++] = arr[j++];
        }
    }
    //一边放完了，说明剩下大的都是另一边的
    if (i == mid + 1) {
        while(j <= end)
            result[k++] = arr[j++];
    }
    if (j == end + 1) {
        while (i <= mid)
            result[k++] = arr[i++];
    }
    for (j = 0, i = start ; j < k; i++, j++) {
        arr[i] = result[j];//把有序的数组还回去
    }

}
void mergeSort(int arr[], int start, int end) {
    if (start >= end)
        return;
    int mid = ( start + end ) / 2;
    mergeSort(arr, start, mid);
    mergeSort(arr, mid + 1, end);
    merge(arr, start, mid, end);
}
void quickSort(int a[],int first,int last){
    if(first >= last) return;
    int mid = a[first];//取第一个值为关键值【中间数】
    int low = first;
    int high = last;
    while(low < high){//循环结束条件是所有左边的数都比中间值小，所有右边的数都比中间值大
        while(low < high && a[high] >= mid){//循环结束时，找到比中间值小的，放左边
            high--;
        }
        a[low] = a[high];//放左边
        while(low < high && a[low] < mid){//循环结束时，找到比中间值大的，放右边
            low++;
        }
        a[high] = a[low];//放右边
    }
    a[low] = mid;//放上中间值
    quickSort(a,first,low - 1);
    quickSort(a,low + 1,last);
}
void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l, j = r, x = q[l + r >> 1];
    while (i < j)
    {
        while (q[i] < x) i++;
        while (q[j] > x) j--;
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

int store[10000];//辅助数组
void countSort(int n){
    int minn = 1e9;
    int maxx = -1e9;
    for(int i = 0;i < n;i++){
        minn = min(minn,nums[i]);//确立下界
        maxx = max(maxx,nums[i]);//确立上界
        store[nums[i]]++;
    }
    for(int i = minn;i <= maxx;i++){
        while(store[i] != 0){
            cout << i << " "; 
            store[i]--;//输出一个删去一个
        }
    }
    cout << "\n";
}
void BucketSort(vector<int>& nums, int k = 3) {
    int n = nums.size();
    int min_num = nums[0];
    int max_num = nums[0];
    // 寻找数组的最大值与最小值
    for (int i = 0; i < n; i++) {
        min_num = min(min_num, nums[i]);
        max_num = max(max_num, nums[i]);
    }
    int bucketNum = (max_num - min_num) / k + 1;
    vector<vector<int>> bucketVector(bucketNum, vector<int>());
    //遍历原数组，将每个元素放入桶中
    for (int i = 0; i < n; i++) {
        int bucketIndex = (nums[i] - min_num) / k;
        bucketVector[bucketIndex].push_back(nums[i]);
    }
    //对桶内的元素进行排序，我这里采用系统自带的排序工具
    for (int i = 0; i < bucketNum; i++) {
        sort(bucketVector[i].begin(),bucketVector[i].end());
    }
    //把每个桶排序好的数据进行合并汇总放回原数组
    nums.clear();
    for (int i = 0; i < bucketNum; i++) {
        for (int num : bucketVector[i]) {
            nums.push_back(num);
        }
    }
}
void radixSort(vector<int> &nums)
{
    // 遍历待排序序列获取最大值,并计算出最大值的位数digits, 确定循环排序的次数.
    int n = nums.size();
    int max_num = nums[0];
    int digits = 1;
    vector<vector<int>> bucketVector(10, vector<int>());

    for(int i = 0; i < n; i++) {
        max_num = max(max_num, nums[i]);
    }
    while(max_num / 10 > 0) {
        digits++, max_num /= 10;
    } 

    for(int i = 1; i <= digits; i++) {
        for(int j = 0; j < n; j++) {
            // 计算出当前元素nums[j]在本轮属于哪一个桶.
            int radix = int(nums[j] / pow(10, i-1)) % 10;
            bucketVector[radix].push_back(nums[j]);
        }
        // 每完成一轮便将桶里的元素按顺序合并放入原序列.
        int k = 0;
        for(int j = 0; j < 10; j++) {
            for(auto num : bucketVector[j]) {
                nums[k++] = num;
            }
            // 同时需要将桶清空以便下一轮的排序.
            bucketVector[j].clear();
        }
    }
}
bool cmp(int a,int b){
    return a > b;
}
int main(){
    int n;
    cin >> n;
    for(int i = 0;i < n;i++){
        cin >> nums[i];
    }
    // selectSort(n);
    // bubbleSort(n);
    // insertSort(n);
    // mergeSort(nums,0,n - 1);
    // quickSort(nums,0,n - 1);
    quick_sort(nums,0,n - 1);
    // countSort(n);
    // sort(nums,nums + n);
    // sort(nums,nums + n,cmp);
    // vector<int> a;
    // a.push_back(8);
    // a.push_back(4);
    // a.push_back(7);
    // sort(a.begin(),a.end());
    // for(int i:a){
    //     cout << i << " ";
    // }
    for(int i = 0;i < n;i++){
        cout << nums[i] << " ";
    }
}